package com.tiyende.credit.loop.request

import com.lib.common.http.OkHttp
import com.lib.common.http.cache.CacheEntity
import com.lib.common.http.cache.CacheMode
import com.lib.common.http.callback.StringCallback
import com.lib.common.http.cookie.CookieJarImpl
import com.lib.common.http.cookie.store.DBCookieStore
import com.lib.common.http.interceptor.HttpLoggingInterceptor
import com.lib.common.http.model.HttpHeaders
import com.lib.common.http.model.Response
import com.tiyende.credit.loop.BuildConfig
import com.tiyende.credit.loop.TiyendeApp
import com.tiyende.credit.loop.configs.TiyendeApiUrl
import com.tiyende.credit.loop.configs.TiyendeApiUrl.addCommonParams
import com.tiyende.credit.loop.configs.TiyendeConfigs
import com.tiyende.credit.loop.utils.aes.TiyendeAesUtil
import com.tiyende.credit.loop.utils.log.JsonFormat
import com.tiyende.credit.loop.utils.log.TiyendeLogger
import com.tiyende.credit.loop.utils.track.TrackPointManager
import okhttp3.OkHttpClient
import org.json.JSONObject
import java.io.File
import java.util.concurrent.TimeUnit
import java.util.logging.Level

/**
 * HttpLoader
 * @Author wwdeng
 * @CreateTime: 2024/11/20 17:38
 * @Annotation：网络请求
 */
class HttpLoader: IHttpLoader {
    private var httpTag: Any? = null

    init {
        OkHttp.getInstance().init(TiyendeApp.app)
        val builder = OkHttpClient.Builder()
        //log相关
        val loggingInterceptor = HttpLoggingInterceptor(TiyendeConfigs.TIYENDE_APPNAME)
        var level = HttpLoggingInterceptor.Level.NONE
        if (BuildConfig.isDebug) {
            level = HttpLoggingInterceptor.Level.BODY
        }
        loggingInterceptor.setPrintLevel(level) //log打印级别，决定了log显示的详细程度
        loggingInterceptor.setColorLevel(Level.INFO) //log颜色级别，决定了log在控制台显示的颜色
        builder.addInterceptor(loggingInterceptor) //添加OkGo默认debug日志
        //第三方的开源库，使用通知显示当前请求的log，不过在做文件下载的时候，这个库好像有问题，对文件判断不准确

        //超时时间设置，默认60秒
        builder.readTimeout(OkHttp.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的读取超时时间
        builder.writeTimeout(OkHttp.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的写入超时时间
        builder.connectTimeout(OkHttp.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS) //全局的连接超时时间
        //自动管理cookie（或者叫session的保持），以下几种任选其一就行
        //builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));            //使用sp保持cookie，如果cookie不过期，则一直有效
//        builder.cookieJar(CookieJarImpl(DBCookieStore(TiyendeApp.app))) //使用数据库保持cookie，如果cookie不过期，则一直有效

        // 其他统一的配置
        // 详细说明看GitHub文档：https://github.com/jeasonlzy/
        OkHttp.getInstance().init(TiyendeApp.app) //必须调用初始化
            .setOkHttpClient(builder.build()) //建议设置OkHttpClient，不设置会使用默认的
            .setCacheMode(CacheMode.NO_CACHE) //全局统一缓存模式，默认不使用缓存，可以不传
            .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE) //全局统一缓存时间，默认永不过期，可以不传
            .setRetryCount(3) //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0

        //添加通用请求头
        val httpHeaders = HttpHeaders()
        httpHeaders.put("appid", TiyendeConfigs.TIYENDE_APPNAME)
        httpHeaders.put("product", TiyendeConfigs.TIYENDE_APPNAME)
        OkHttp.getInstance().addCommonHeaders(httpHeaders)
    }

    /**
     * post 请求
     */
    override fun post(url: String, params: JSONObject,callback: IHttpCallback) {
        params.addCommonParams()
        val aesParams = TiyendeAesUtil.encryptDefault(params.toString())
        TiyendeLogger.e("HttpUrl：  $url")
        TiyendeLogger.e("HttpParams： $params")
        TiyendeLogger.e("HttpParams AES：  $aesParams")

        OkHttp.post<String>(url) // 请求方式和请求url
            .tag(httpTag) // 请求的 tag, 主要用于取消对应的请求
            .upString(aesParams)
            .execute(object : StringCallback() {
                override fun onSuccess(response: Response<String>) {
                    val body = response.body()
                    if (response.code() != 200 || body == null || body.isEmpty()){
                        val errorObj = JSONObject()
                        errorObj.put("errorCode",response.code())
                        errorObj.put("errorMsg",response.message())
                        callback.onRequestError(errorObj)
                        return
                    }

                    val result = TiyendeAesUtil.decryptDefault(body)
                    if (result.isNotEmpty()){
                        Thread { TiyendeLogger.i("\nhttpUrl:$url\nresult:${JsonFormat.format(result)}") }.start()
                        val data = JSONObject(result)
                        callback.onRequestSuccess(data)
                    } else {
                        val errorObj = JSONObject()
                        errorObj.put("errorCode",-1)
                        errorObj.put("errorMsg","http request error $result")
                        callback.onRequestError(errorObj)
                    }
                }

                override fun onError(response: Response<String>) {
                    val errorObj = JSONObject()
                    errorObj.put("errorCode",response.code())
                    errorObj.put("errorMsg",response.message())
                    callback.onRequestError(errorObj)
                }
                override fun onFinish() {
                    callback.onRequestFinish()
                }
            })
    }

    /**
     * 文件上传
     */
    override fun upload(filePath: String, callback: StringCallback) {
        if (filePath.isEmpty()){
            return
        }
        val httpUrl = TiyendeApiUrl.getTiyendeHttpUrl(true)
        OkHttp.post<String>(httpUrl) // 请求方式和请求url
            .tag(httpTag) // 请求的 tag, 主要用于取消对应的请求
            .params("image",File(filePath))   //这种方式为一个key，对应一个文件
            .isMultipart(true)
            .execute(callback)
    }

    /**
     * 添加打点事件
     */
    override fun addPoint(eventName: String, remark: String?, callback: IHttpCallback) {
        TiyendeLogger.e(">>>>>>>>>>>>>>eventName：$eventName，remark：$remark")
        val eventType = eventName.uppercase()//转大写
        if (remark != null){
            TrackPointManager.getInstance().track(eventType,remark)
        } else {
            TrackPointManager.getInstance().track(eventType,"")
        }


//        val httpUrl = TiyendeApiUrl.getTiyendeHttpUrl()
//        val params = JSONObject().addCommonParams().apply {
//            put("path", TiyendeApiPath.TIYENDE_PATH.TIYENDE_API_TRACK_EVENT_PATH)
//            put("type",eventType)//事件类型
//            put("remark",remark)//事件备注
//        }
//
//        val aesParams = TiyendeAesUtil.encryptDefault(params.toString())
//        TiyendeLogger.e("event url：  $httpUrl")
//        TiyendeLogger.e("event params： $params")
//        TiyendeLogger.e("event params AES：  $aesParams")
//        OkHttp.post<String>(httpUrl) // 请求方式和请求url
//            .tag(httpTag) // 请求的 tag, 主要用于取消对应的请求
//            .upString(aesParams)
//            .execute(object : StringCallback() {
//                override fun onSuccess(response: Response<String>) {
//                    val result = TiyendeAesUtil.decryptDefault(response.body())
//                    Thread { TiyendeLogger.i("\nevent type:$eventType\nevent result:${JsonFormat.format(result)}") }.start()
//                }
//                override fun onError(response: Response<String>) {
//                }
//                override fun onFinish() {
//                }
//            })
    }

    /**
     * 设置请求tag
     */
    override fun setTag(tag: Any) {
        this.httpTag = tag
    }

    /**
     * 取消请求
     */
    override fun cancelTag(tag: Any) {
//        OkHttp.getInstance().cancelTag(tag)
    }
}